package cn.lx.es.query.utils;

import cn.lx.es.query.annotation.ESMapping;
import cn.lx.es.query.annotation.ESMetaData;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;

/**
 * @author wcy
 * @version 1.0
 * @description: 索引工具类
 * @date 2025-07-02 下午12:35
 */
public class IndexTools {


    /**
     * 获取索引元数据：indexname、indextype
     * @param clazz
     * @return
     */
    public static MetaData getIndexType(Class<?> clazz){
        String indexname = "";
        String indextype = "";
        if(clazz.getAnnotation(ESMetaData.class) != null){
            indexname = clazz.getAnnotation(ESMetaData.class).indexName();
            indextype = clazz.getAnnotation(ESMetaData.class).indexType();
            if(indextype == null || indextype.equals("")){indextype = "_doc";}
            MetaData metaData = new MetaData(indexname,indextype);
            metaData.setPrintLog(clazz.getAnnotation(ESMetaData.class).printLog());
            if(Tools.arrayISNULL(clazz.getAnnotation(ESMetaData.class).searchIndexNames())) {
                metaData.setSearchIndexNames(new String[]{indexname});
            }else{
                metaData.setSearchIndexNames((clazz.getAnnotation(ESMetaData.class).searchIndexNames()));
            }
            return metaData;
        }
        return null;
    }

    /**
     * 获取索引元数据：主分片、备份分片数的配置
     * @param clazz
     * @return
     */
    public static MetaData getShardsConfig(Class<?> clazz){
        int number_of_shards = 0;
        int number_of_replicas = 0;
        if(clazz.getAnnotation(ESMetaData.class) != null){
            number_of_shards = clazz.getAnnotation(ESMetaData.class).numberOfShards();
            number_of_replicas = clazz.getAnnotation(ESMetaData.class).numberOfReplicas();
            MetaData metaData = new MetaData(number_of_shards,number_of_replicas);
            metaData.setPrintLog(clazz.getAnnotation(ESMetaData.class).printLog());
            return metaData;
        }
        return null;
    }

    /**
     * 获取索引元数据：indexname、indextype、主分片、备份分片数的配置
     * @param clazz
     * @return
     */
    public static MetaData getMetaData(Class<?> clazz){
        String indexname = "";
        String indextype = "";
        int number_of_shards = 0;
        int number_of_replicas = 0;
        if(clazz.getAnnotation(ESMetaData.class) != null){
            indexname = clazz.getAnnotation(ESMetaData.class).indexName();
            indextype = clazz.getAnnotation(ESMetaData.class).indexType();
            if(indextype == null || indextype.equals("")){indextype =  "_doc";}
            number_of_shards = clazz.getAnnotation(ESMetaData.class).numberOfShards();
            number_of_replicas = clazz.getAnnotation(ESMetaData.class).numberOfReplicas();
            MetaData metaData = new MetaData(indexname,indextype,number_of_shards,number_of_replicas);
            metaData.setPrintLog(clazz.getAnnotation(ESMetaData.class).printLog());
            if(Tools.arrayISNULL(clazz.getAnnotation(ESMetaData.class).searchIndexNames())) {
                metaData.setSearchIndexNames(new String[]{indexname});
            }else{
                metaData.setSearchIndexNames((clazz.getAnnotation(ESMetaData.class).searchIndexNames()));
            }
            return metaData;
        }
        return null;
    }

    /**
     * 获取配置于Field上的mapping信息，如果未配置注解，则给出默认信息
     * @param field
     * @return
     */
    public static MappingData getMappingData(Field field){
        if(field == null){
            return null;
        }

        ReflectionUtils.makeAccessible(field);
        MappingData mappingData = new MappingData();
        mappingData.setFieldName(field.getName());
        if(field.getAnnotation(ESMapping.class) != null){
            ESMapping esMapping = field.getAnnotation(ESMapping.class);
            mappingData.setDatatype(esMapping.datatype().toString());
//            mappingData.setAnalyzedtype(esMapping.analyzedtype().toString());
            mappingData.setAnalyzer(esMapping.analyzer().toString());
            mappingData.setNgram(esMapping.ngram());
            mappingData.setIgnoreAbove(esMapping.ignoreAbove());
            mappingData.setSearchAnalyzer(esMapping.searchAnalyzer().toString());
            if(mappingData.getDatatype().equals("text")) {
                mappingData.setKeyword(esMapping.keyword());
            }else{
                mappingData.setKeyword(false);
            }
            mappingData.setSuggest(esMapping.suggest());
            mappingData.setAllowSearch(esMapping.allowSearch());
            mappingData.setCopyTo(esMapping.copyTo());
            mappingData.setNestedClass(esMapping.nestedClass());
            if(!StringUtils.isEmpty(esMapping.nullValue())){
                mappingData.setNullValue(esMapping.nullValue());
            }
        }else{
            //todo 待优化为根据类型 BigDecimal Long Integer
            mappingData.setDatatype("text");
//            mappingData.setAnalyzedtype("analyzed");
            mappingData.setAnalyzer("standard");
            mappingData.setNgram(false);
            mappingData.setIgnoreAbove(256);
            mappingData.setSearchAnalyzer("standard");
            mappingData.setKeyword(true);
            mappingData.setSuggest(false);
            mappingData.setAllowSearch(true);
            mappingData.setCopyTo("");
            mappingData.setNestedClass(null);
        }
        return mappingData;
    }

    /**
     * 批量获取配置于Field上的mapping信息，如果未配置注解，则给出默认信息
     * @param clazz
     * @return
     */
    public static MappingData[] getMappingData(Class<?> clazz){
        Field[] fields = clazz.getDeclaredFields();
        MappingData[] mappingDataList = new MappingData[fields.length];
        for (int i = 0; i < fields.length; i++) {
            if(fields[i].getName().equals("serialVersionUID")){
                continue;
            }
            mappingDataList[i] = getMappingData(fields[i]);
        }
        return mappingDataList;
    }
}
